var hx = require("hbuilderx");
const fs = require("fs")
const path = require("path")

//该方法将在插件激活的时候调用
function activate(context) {
   let disposable = hx.commands.registerCommand('format-all', (param) => {
      const {
         fsPath
      } = param;

      if (!check(fsPath)) {
         return;
      }

      formatAll(fsPath);
   });
   //订阅销毁钩子，插件禁用的时候，自动注销该command。
   context.subscriptions.push(disposable);
}
//该方法将在插件禁用的时候调用（目前是在插件卸载的时候触发）
function deactivate() {

}
module.exports = {
   activate,
   deactivate
}

function check(dir) {
   if (!dir) {
      hx.window.showInformationMessage('指定目录无效');
      return false;
   }
   if (!fs.existsSync(dir)) {
      hx.window.showInformationMessage('指定目录不存在');
      return false;
   }
   if (!fs.statSync(dir).isDirectory()) {
      hx.window.showInformationMessage('不是一个目录');
      return false;
   }

   return true
}

function formatAll(dir) {
   const fileter = getFilter()
   // 获取所有文件
   const files = readDir(dir, fileter).filter(fileter);
   if (!files.length) {
      return hx.window.showWarningMessage(`未匹配到满足格式化条件的文件，请检查正则设置！！！`);
   }

   const funcs = createFuncs(files);
   funcs.push(() => {
      return hx.window.showInformationMessage(`格式化完成，共格式化文件：${files.length} 个`);
   })

   execSeriesFuncs(funcs);
}

function getFilter() {
   let config = hx.workspace.getConfiguration()
   let includes = config.get("3.includes");
   let excludes = config.get("4.excludes");
   const includesTest = (name) => {
      return includes ? new RegExp(`${includes}`).test(name) : true
   }
   const excludesTest = (name) => {
      return excludes ? new RegExp(`${excludes}`).test(name) : false
   }

   return (name) => {
      return !!includesTest(name) && !excludesTest(name)
   }
}

function readDir(dir, filter) {
   let files = [];
   const items = fs.readdirSync(dir).filter(name => !name.startsWith('.'));
   for (let item of items) {
      const itemPath = path.join(dir, item);
      if (fs.statSync(itemPath).isDirectory()) {
         files.push(...readDir(itemPath, filter))
      }
      else {
         files.push(itemPath);
      }
   }
   return files
}

function createFuncs(files) {
   let config = hx.workspace.getConfiguration()
   let isSave = config.get("1.is.save");
   let isClose = config.get("2.is.close");

   const funcs = [];
   for (let file of files) {
      funcs.push(() => {
         hx.window.setStatusBarMessage('开始格式化文件：' + file, 500, 'info');
         return hx.workspace.openTextDocument(file)
      })
      funcs.push(() => {
         return hx.commands.executeCommand("editor.action.format");
      })
      funcs.push(() => {
         return isSave ? hx.commands.executeCommand("workbench.action.files.save") : Promise.resolve(void 0);
      })
      funcs.push(() => {
         return isSave && isClose ? hx.commands.executeCommand("workbench.action.closeActiveEditor") : Promise.resolve(void 0);
      })
      funcs.push(() => {
         return new Promise(res => {
            setTimeout(() => {
               res(void 0);
            }, 50)
         })
      })
   }
   return funcs;
}

function execSeriesFuncs(funcs) {
   return new Promise((resolve, reject) => {
      const _this = this;

      runFunc(resolve, reject);

      function runFunc() {
         const func = funcs.shift();
         if (func) {
            func().then(() => {
               runFunc();
            }).catch(() => {
               reject(void 0)
            })
         }
         else {
            resolve(void 0)
         }
      }
   });
}